// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//
#pragma once

#include <fmt/format.h>
#include <string>

namespace kumo::pollux::exec {
    /// Define the internal execution state for hash/nested loop join probe. The
    /// valid state transition is depicted as follows:
    ///
    ///                           +--------------------------------+
    ///                           ^                                |
    ///                           |                                V
    ///   kWaitForBuild -->  kRunning  -->  kWaitForPeers --> kFinish
    ///         ^                                |
    ///         |                                v
    ///         +--------------------------------+
    ///
    enum class ProbeOperatorState {
        /// Wait for hash build operators to build the next hash table to join.
        kWaitForBuild = 0,
        /// The running state that join the probe input with the build table.
        kRunning = 1,
        /// This state has different handling for hash and nested loop join probe.
        /// For hash probe, wait for all the peer probe operators to finish processing
        /// inputs.
        /// This state only applies when disk spilling is enabled. The last finished
        /// operator will notify the build operators to build the next hash table
        /// from the spilled data. Then all the peer probe operators will wait for
        /// the next hash table to build.
        /// For nested loop join probe, when doing right/full join, after the
        /// completion of emitting matching and probe-side mismatching data, non-last
        /// operators wait for the last probe operator to take over build-side
        /// mismatching data.
        kWaitForPeers = 2,
        /// The finishing state.
        kFinish = 3,
    };

    std::string probeOperatorStateName(ProbeOperatorState state);
} // namespace kumo::pollux::exec

template<>
struct fmt::formatter<kumo::pollux::exec::ProbeOperatorState>
        : formatter<int> {
    auto format(kumo::pollux::exec::ProbeOperatorState s, format_context &ctx)
    const {
        return formatter<int>::format(static_cast<int>(s), ctx);
    }
};
